/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.etrs.formathlon.entity.formation;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import net.etrs.formathlon.entity.utilisateur.Personnel;
import net.etrs.formathlon.entity.utils.ComparableEvenThoughUnpersisted;
import net.etrs.formathlon.persistance.utils.JpaRequestNames;

/**
 * Entité symbolisant l'inscription d'une personne qui passera dans plusieurs 
 * états selon l'avancé de l'inscrition.
 * @author OPIF
 */
@Entity
@NamedQueries({
    @NamedQuery(name = JpaRequestNames.LISTE_INSCRIPTIONS_A_VALIDER,
    query = "SELECT object(i) FROM Inscription i, Personnel p, Utilisateur u "
    + "WHERE i.personnel=p AND u = p.utilisateur AND u.entite LIKE :entite AND i.etat=:etat"),
    @NamedQuery(name = JpaRequestNames.LISTE_INSCRIPTION_DU_FORMATEUR,
    query = "SELECT object(i) FROM Inscription i WHERE i.personnel=:personnel AND i.etat!=:etat "),
    @NamedQuery(name = JpaRequestNames.LISTE_INSCRIPTION_VALIDEES,
    query = "SELECT object(i) FROM Inscription i WHERE i.session=:session "
    + "AND (i.etat=:etatValideeDiv OR i.etat=:etatVerrouillee)"),
    @NamedQuery(name = JpaRequestNames.LISTE_INSCRIPTION_NON_VALIDEES,
    query = "SELECT object(i) FROM Inscription i WHERE i.session=:session "
    + "AND (i.etat!=:etatValideeDiv AND i.etat!=:etatVerrouillee)"),
    @NamedQuery(name = JpaRequestNames.INSCRIPTION_DEJA_FAITE,
    query = "SELECT object(i) FROM Inscription i WHERE i.session = :session "
    + "AND i.personnel = :personnel")
})
public class Inscription extends ComparableEvenThoughUnpersisted<Inscription> {

    /**
     * Identifiant.
     */
    private static final long serialVersionUID = 1L;
    /**
     * Identifiant de la personne.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    /**
     * Personne concernée par l'inscription.
     */
    @ManyToOne
    private Personnel personnel;
    /**
     * Session à laquelle est inscrite la personne.
     */
    @ManyToOne
    private Session session;
    /**
     * Etat de la demande d'inscription.
     */
    @Enumerated(EnumType.STRING)
    private Etat etat;
    /**
     * Motif du désistement.
     */
    private String motifDesist;
    /**
     * Booléen permettant de savoir si la donnée est archivée.
     */
    private boolean archive;

    @Override
    public Long getId() {
        return id;
    }

    /**
     * Setter de l'id.
     * @param id 
     */
    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return String.format("Inscription id=%d, etat=%s", id, etat.getLibelle());
    }

    @Override
    public boolean isArchive() {
        return archive;
    }

    @Override
    public void setArchive(boolean archive) {
        this.archive = archive;
    }

    /**
     * @return the personnel
     */
    public Personnel getPersonnel() {
        return personnel;
    }

    /**
     * @param personnel the personnel to set
     */
    public void setPersonnel(Personnel personnel) {
        this.personnel = personnel;
    }

    /**
     * @return the session
     */
    public Session getSession() {
        return session;
    }

    /**
     * @param session the session to set
     */
    public void setSession(Session session) {
        this.session = session;
    }

    /**
     * @return the etat
     */
    public Etat getEtat() {
        return etat;
    }

    /**
     * @param etat the etat to set
     */
    public void setEtat(Etat etat) {
        this.etat = etat;
    }

    /**
     * Permet de savoir si une inscription est annulable suivant son etat.
     * @return vrai ou faux
     */
    public boolean isAnnulable() {
        if (etat.equals(Etat.DEMANDEE) || etat.equals(Etat.VALIDEE_COURS)) {
            return true;
        }
        return false;
    }

    /**
     * Permet de savoir si une personne peut se desister d une formation.
     * @return vrai ou faux
     */
    public boolean isDesistable() {
        if (etat.equals(Etat.VALIDEE_DIVISION)) {
            return true;
        }
        return false;
    }

    /**
     * Permet de savoir si une inscription peut etre supprimer
     * (elle sera en fait archivée).
     * @return vrai ou faux
     */
    public boolean isSupprimable() {
        if (etat.equals(Etat.REFUSEE) || etat.equals(Etat.ANNULEE)) {
            return true;
        }
        return false;
    }

    /**
     * @return the motifDesist
     */
    public String getMotifDesist() {
        return motifDesist;
    }

    /**
     * @param motifDesist the motifDesist to set
     */
    public void setMotifDesist(String motifDesist) {
        this.motifDesist = motifDesist;
    }

    /**
     * Etat de l inscription.
     */
    public enum Etat {

        DEMANDEE("Demandée"),
        VALIDEE_COURS("Validée par le chef de cours"),
        VALIDEE_DIVISION("Validée par le chef de division"),
        REFUSEE("Refusée"),
        ANNULEE("Annulée"),
        SUPPRIMEE("Supprimée"),
        VERROUILLEE("Verrouillée"),
        PARTICIPEE("Participée"),
        NON_PARTICIPEE("Non participée");
        private String libelle;
        public static String[] stringValues;
        
        /**
         * Constructeur par défaut.
         * @param libelle 
         */
        Etat(String libelle) {
            this.libelle = libelle;
        }
        
        /**
         * 
         * @return Le nom de l'état
         */
        public String getLibelle() {
            return this.libelle;
        }

        /**
         * Renvoie la liste des états possible.
         * @return 
         */
        public static String[] stringValues() {
            if (stringValues == null) {
                StringBuilder liste = new StringBuilder();
                for (Etat etat : values()) {
                    if (liste.length() != 0) {
                        liste.append("/");
                    }
                    liste.append(etat.libelle);
                }
                stringValues = liste.toString().split("/");
            }
            return stringValues;
        }
    }
}
